//
//  fixxApiObjectMapper.m
//  fixx
//
//  Created by Jonathan Williamson on 26/11/2009.
//  Copyright 2009 Hedgehog Lab. All rights reserved.
//

#import "fixxApiObjectMapper.h"
#import "ASIHTTPRequest.h"
#import "JSON.h"

@implementation fixxApiObjectMapper

//******************************************

- (id)initWithUsername: (NSString *)_username password: (NSString *)_password andUrl: (NSString *)_url
{
	username = [NSString stringWithString:_username];
	password = [NSString stringWithString:_password];
	url = [NSString stringWithString:_url];
	
	return self;
}

//******************************************

- (id) requestObjectForApiExtension: (NSString *)extention
{	
	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
	
	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
	[myRequest setUsername:username];
	[myRequest setPassword:password];
	
	NSString *authInfo = [NSString stringWithString:@"Basic "];
	authInfo = [authInfo stringByAppendingString: username];
	authInfo = [authInfo stringByAppendingString:@":"];
	authInfo = [authInfo stringByAppendingString:password];
	
	[myRequest addRequestHeader:@"Authorization" value:authInfo];
	
	[myRequest start];
	
	SBJsonParser *jsonParser = [SBJsonParser new];
	id objectData = nil;
	if([myRequest responseStatusCode] == 200)
		objectData = [[jsonParser objectWithString: myRequest.responseString] retain];
	
	[jsonParser release];
	
	return objectData;
}

//******************************************

- (id) requestObjectForApiExtension: (NSString *)extention andIds: (NSArray *)Ids
{
	int hashCount = 0;
	for(int i=0; i<[extention length]; ++i)
		if([extention characterAtIndex:i] == '#') ++hashCount;
	
	if(hashCount != [Ids count]) return nil;
		
	NSString *tempUrl = [NSString stringWithString:[url stringByAppendingString:extention]];
		
	NSInteger count = 1;
	for(NSNumber *ID in Ids)
	{
		tempUrl = [tempUrl stringByReplacingOccurrencesOfString:[@"#" stringByAppendingString:[[NSNumber numberWithInt:count] stringValue]] withString:[ID stringValue]];
		++count;
	}
	
	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
	
	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
	[myRequest setUsername:username];
	[myRequest setPassword:password];
	
	NSString *authInfo = [NSString stringWithString:@"Basic "];
	authInfo = [authInfo stringByAppendingString: username];
	authInfo = [authInfo stringByAppendingString:@":"];
	authInfo = [authInfo stringByAppendingString:password];
	
	[myRequest addRequestHeader:@"Authorization" value:authInfo];
	
	[myRequest start];
	
	SBJsonParser *jsonParser = [SBJsonParser new];
	id objectData = nil;
	if([myRequest responseStatusCode] == 200) objectData = [[jsonParser objectWithString: myRequest.responseString] retain];
	
	[jsonParser release];
	
	return objectData;
}

//******************************************

- (NSInteger) sendObject: (NSMutableDictionary *)object forApiExtension: (NSString *)extention andRequestMethod: (NSString *)method
{	
	if(![method isEqualToString:@"POST"] && ![method isEqualToString:@"PUT"]) return -1;
	
	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
	
	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
	[myRequest setUsername:username];
	[myRequest setPassword:password];
	
	NSString *authInfo = [NSString stringWithString:@"Basic "];
	authInfo = [authInfo stringByAppendingString: username];
	authInfo = [authInfo stringByAppendingString:@":"];
	authInfo = [authInfo stringByAppendingString:password];
	
	SBJsonWriter *jsonWriter = [SBJsonWriter new];
	
	[myRequest addRequestHeader:@"Authorization" value:authInfo];
	NSString *postData = [jsonWriter stringWithObject:object];
	[myRequest appendPostData: [postData dataUsingEncoding:NSUTF8StringEncoding]];
	[myRequest setRequestMethod: method];
	
	[myRequest start];
	 
	[jsonWriter release];
	
	return [myRequest responseStatusCode];
}

//******************************************

- (NSInteger) sendObject: (NSMutableDictionary *)object forApiExtension: (NSString *)extention andIds: (NSArray *)Ids andRequestMethod: (NSString *)method
{
	if(![method isEqualToString:@"POST"] && ![method isEqualToString:@"PUT"]) return -1;
	
	int hashCount = 0;
	for(int i=0; i<[extention length]; ++i)
		if([extention characterAtIndex:i] == '#') ++hashCount;
	
	if(hashCount != [Ids count]) return nil;
	
	NSString *tempUrl = [NSString stringWithString:[url stringByAppendingString:extention]];
	
	NSInteger count = 1;
	for(NSNumber *ID in Ids)
	{
		tempUrl = [tempUrl stringByReplacingOccurrencesOfString:[@"#" stringByAppendingString:[[NSNumber numberWithInt:count] stringValue]] withString:[ID stringValue]];
		++count;
	}
	
	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
	
	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
	[myRequest setUsername:username];
	[myRequest setPassword:password];
	
	NSString *authInfo = [NSString stringWithString:@"Basic "];
	authInfo = [authInfo stringByAppendingString: username];
	authInfo = [authInfo stringByAppendingString:@":"];
	authInfo = [authInfo stringByAppendingString:password];
	
	SBJsonWriter *jsonWriter = [SBJsonWriter new];
	
	[myRequest addRequestHeader:@"Authorization" value:authInfo];
	NSString *postData = [jsonWriter stringWithObject:object];
	[myRequest appendPostData: [postData dataUsingEncoding:NSUTF8StringEncoding]];
	[myRequest setRequestMethod: method];
	
	[myRequest start];
	
	[jsonWriter release];
	
	return [myRequest responseStatusCode];
}

//******************************************

- (id) deleteObjectForApiExtension: (NSString *)extention andIds: (NSArray *)Ids
{
	int hashCount = 0;
	for(int i=0; i<[extention length]; ++i)
		if([extention characterAtIndex:i] == '#') ++hashCount;
	
	if(hashCount != [Ids count]) return nil;
	
	NSString *tempUrl = [NSString stringWithString:[url stringByAppendingString:extention]];
	
	NSInteger count = 1;
	for(NSNumber *ID in Ids)
	{
		tempUrl = [tempUrl stringByReplacingOccurrencesOfString:[@"#" stringByAppendingString:[[NSNumber numberWithInt:count] stringValue]] withString:[ID stringValue]];
		++count;
	}
	
	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
	
	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
	[myRequest setUsername:username];
	[myRequest setPassword:password];
	
	NSString *authInfo = [NSString stringWithString:@"Basic "];
	authInfo = [authInfo stringByAppendingString: username];
	authInfo = [authInfo stringByAppendingString:@":"];
	authInfo = [authInfo stringByAppendingString:password];
	
	[myRequest addRequestHeader:@"Authorization" value:authInfo];
	[myRequest requestMethod:@"DELETE"];
	
	[myRequest start];
	
	return [myRequest responseStatusCode];
}

//******************************************

// Projects
// --------
- (NSMutableArray *)getAllProjects
{
	return [self requestObjectForApiExtension:@"api/projects"];
}

- (NSMutableDictionary *)getProjectWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/projects/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSInteger)createProjectFromObject: (NSMutableDictionary *)object
{
	return [self sendObject:object forApiExtension:@"api/projects" andRequestMethod:@"POST"];
}

- (NSInteger)updateProject: (NSInteger)ID fromObject: (NSMutableDictionary *)object
{
	return [self sendObject:object forApiExtension:@"api/projects/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"PUT"];
}


// Resolutions
// -----------

- (NSMutableArray *)getAllResolutionsForProjectWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/projects/#1/resolutions" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSMutableArray *)getAllIssueTypesForProjectWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/projects/#1/issue-types" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}


// Areas
// -----

- (NSMutableArray *)getAllAreasForProjectWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/projects/#1/areas" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSMutableArray *)getAllVersionsForProjectWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/projects/#1/versions" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSMutableArray *)getReleasedVersionsForProjectWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/projects/#1/versions?type=fixfor" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}


// Issues
// ------

- (NSMutableArray *)getAllIssuesForProjectWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/projects/#1/issues" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSMutableArray *)getAllIssuesWithQuerystrings: (NSArray *)strings
{
	NSString *temp = [NSString stringWithString:@"api/issues?"];
	for(NSString *string in strings)
	{
		temp = [temp stringByAppendingString:string];
		temp = [temp stringByAppendingString:@"&"];
	}
	temp = [temp substringToIndex:([temp length]-2)];
	
	return [self requestObjectForApiExtension:temp];
}

- (NSMutableDictionary *)getIssueWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"/api/issues/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSInteger)createIssueFromObject: (NSMutableDictionary *)object
{
	return [self sendObject:object forApiExtension:@"api/issues" andRequestMethod:@"POST"];
}

- (NSInteger)updateIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object
{
	return [self sendObject:object forApiExtension:@"api/issues/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"PUT"];
}


// Comments
// --------

- (NSMutableArray *)getAllCommentsForIssueWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/issues/#1/comments" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSInteger)addCommentToIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object
{
	return [self sendObject:object forApiExtension:@"api/issues/#1/comments" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"POST"];
}

- (NSInteger)deleteCommentWithId: (NSInteger)commentId fromIssueWithId: (NSInteger)issueId
{
	[self deleteObjectForApiExtension: @"api/issues/#1/comments/#2" andIds: [NSArray arrayWithObjects:[NSNumber numberWithInt:issueId], [NSNumber numberWithInt:commentId], nil]];
}


// Timelogs
// --------

- (NSMutableDictionary *)getAllTimelogsForIssueWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/issues/#1/timelogs" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSInteger)addTimelogToIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object
{
	return [self sendObject:object forApiExtension:@"api/issues/#1/timelogs" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"POST"];
}

- (NSInteger)deleteTimelogWithId: (NSInteger)timelogId fromIssueWithId: (NSInteger)issueId
{
	[self deleteObjectForApiExtension: @"api/issues/#1/timelogs/#2" andIds: [NSArray arrayWithObjects:[NSNumber numberWithInt:issueId], [NSNumber numberWithInt:timelogId], nil]];
}


// Tags
// ----

- (NSMutableArray *)getAllTagsForIssueWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/issues/#1/tags" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSInteger)addTagToIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object
{
	return [self sendObject:object forApiExtension:@"api/issues/#1/tags" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"POST"];
}

- (NSInteger)deleteTagWithId: (NSInteger)tagId fromIssueWithId: (NSInteger)issueId
{
	[self deleteObjectForApiExtension: @"api/issues/#1/tags/#2" andIds: [NSArray arrayWithObjects:[NSNumber numberWithInt:issueId], [NSNumber numberWithInt:tagId], nil]];
}

// Changelogs
// ----------

- (NSMutableArray *)getAllChangelogsForIssueWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/issues/#1/changelogs" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}


// Users
// -----

- (NSMutableArray *)getAllUsers
{
	return [self requestObjectForApiExtension:@"api/users"];
}

- (NSMutableDictionary *)getUserWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/issues/#1/changelogs" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSMutableDictionary *)getUserWithUsername: (NSString *)_username
{
	return [self requestObjectForApiExtension:[@"api/users/" stringByAppendingString:_username]];
}

- (NSMutableArray *)getUsersForProjectWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/projects/#1/users" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSMutableArray *)getClientsForProjectWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/projects/#1/clients" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSMutableArray *)getUsersWatchingIssueWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/issues/#1/watchers" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (NSInteger)subscribeUserWithId: (NSInteger)userId toIssueWithId: (NSInteger)issueId
{
	//return [self sendObject:nil forApiExtension:@"api/issues/#1/watchers/#2" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:issueId], [NSNumber numberWithInt:userId], nil] andRequestMethod:@"PUT"];
	//Wierd!
	return 0;
}


// Priorities
// ----------

- (NSMutableArray *) getAllPriorities
{
	return [self requestObjectForApiExtension:@"api/priorities"];
}

- (NSMutableDictionary *) getPriorityWithId: (NSInteger)ID
{
	return [self requestObjectForApiExtension:@"api/priorities/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
}

- (void) dealloc
{
	[super dealloc];
}

@end
